#pragma once

#define WIN32_LEAN_AND_MEAN
#define DIRECTINPUT_VERSION 0x0800
#include <windows.h>
#include <dinput.h>

#include <vector>

namespace Diol
{

/*
	The DeviceInstance is a wrapper around the DirectInput DIDEVICEINSTANCE structure
	See http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.dideviceinstance(v=vs.85).aspx
	It is basically a descriptor/identifier of a DirectInput device 
*/
struct DeviceInstance
{
public:
	DeviceInstance();
	DeviceInstance( LPCDIDEVICEINSTANCE deviceObjectInstance );
	DeviceInstance( const DeviceInstance& other );

	bool operator==( const DeviceInstance& other ) const;
	DeviceInstance& operator=( const DeviceInstance& other );

	const GUID&			getGuidInstance() const		{ return mDeviceInstance.guidInstance; }

	const GUID&			getGuidProduct() const		{ return mDeviceInstance.guidProduct; }

	// This is the raw information about the device type. It combines the type and subtype
	// Method below allow easier acces to one or the other
	DWORD				getDwDevType() const		{ return mDeviceInstance.dwDevType; }
	DWORD				getDeviceType() const		{ return GET_DIDEVICE_TYPE( getDwDevType() ); }
	DWORD				getDeviceSubType() const	{ return GET_DIDEVICE_SUBTYPE( getDwDevType() ); }

	std::string			getInstanceName() const;
	std::string			getProductName() const;

	const GUID&			getFFDriver() const			{ return mDeviceInstance.guidFFDriver; }
	
	WORD				getUsagePage() const		{ return mDeviceInstance.wUsagePage; }
	WORD				getUsage() const			{ return mDeviceInstance.wUsage; }

private:
	const TCHAR*		getRawInstanceName() const	{ return mDeviceInstance.tszInstanceName; }
	const TCHAR*		getRawProductName() const	{ return mDeviceInstance.tszProductName; }
	
	DIDEVICEINSTANCE	mDeviceInstance;
	mutable std::string	mInstanceName;		// Cached UTF-8 version of instance name
	mutable std::string	mProductName;		// Same of product name
};

typedef std::vector<DeviceInstance> DeviceIdentifiers;

}

